using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PowersourceUIToolkit;
using UCL.Powersource;
using UCL.Powersource.Analysis;
using UCL.Powersource.ViewModels;
using System.Diagnostics;
using System.Threading;
using System.Windows.Threading;
using Powersource_UnitTests.TestHelpers;
using System.ComponentModel;

namespace Powersource_UnitTests.StatisticResolving
{
    [TestClass]
    public class StatisticManagerQueueTests
    {

        private TestContext testContextInstance;
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }


        Bootstrapper bs;
        IPowersourceExt IPowersourceExt;
        private PowersourceMainViewModel MainVM;
        Dispatcher CDispatcher;


        private void InstantiateTestBootStrapper(params Type[] types)
        {
            if (types==null) types=new Type[0];
            TestBootstrappers.LogHelper.CreateTestLog(TestContext);
            bs = TestBootstrappers.BootStrapperLoader.CreateDummyVisualStudio_RealStatMan_RealRepMan_RealTFS(types);
            IPowersourceExt = PowersourceConnector.GetExtensibilityPoint();
            MainVM = ViewModelLocator.GetViewModel<PowersourceMainViewModel>();
            MainVM.Activate();
            MainVM.TryTFSConnect();

        }

        ILog Log
        {
            get { return LogManager.DefaultInstance; }
        }

        [TestInitialize]
        public void StartUp()
        {

        }
        [TestCleanup]
        public void CleanUp()
        {
            MainVM = null;
            bs.Dispose();
            LogManager.DefaultInstance.Dispose();
        }

        //private bool EnqueueOneStatisticOneTeamOneTimeFrame_Finished;
        //private bool EnqueueOneStatisticOneTeamOneTimeFrame_Started;
        [TestMethod]
        public void EnqueueOneStatisticOneTeamOneTimeFrame()
        {
            InstantiateTestBootStrapper();
            var EnqueueOneStatisticOneTeamOneTimeFrame_Finished = false;
            var EnqueueOneStatisticOneTeamOneTimeFrame_Started = false;
            var sm = IPowersourceExt.StatisticManager;
            var queue = sm.StatisticManagerQueue;
            var totalCnt = 1;
            int allowedDiffFromTotal = totalCnt;
            var queueUpdated = new EventHandler<StatisticManagerQueueUpdatedEventArgs>((sender, e) => Queue_StatisticManagerQueueUpdated(sender, e, totalCnt, ref allowedDiffFromTotal));
            var queuePropUpdate = new PropertyChangedEventHandler((sender, e) => Queue_PropertyChanged(sender, e, ref EnqueueOneStatisticOneTeamOneTimeFrame_Started, ref EnqueueOneStatisticOneTeamOneTimeFrame_Finished));
            queue.StatisticManagerQueueUpdated += queueUpdated;
            queue.PropertyChanged += queuePropUpdate;
            string excStr;
            Exception ComputationException;
            try
            {
                var stat = sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.AccelerationStatistics));
                var team = MainVM.CurrentTfsTeamProjectCollectionConfiguration.First();
                var tf = MainVM.CurrentTfsTeamProjectCollectionConfiguration.ProjectCollectionTimeFrames.First();

                queue.EnqueueStatisticRecalculationAsync(stat, team, tf, true);
                int i = 0;
                Trace.TraceInformation("Entering waiting loop");
                while (!EnqueueOneStatisticOneTeamOneTimeFrame_Finished)
                {

                    DispatcherUtil.DoEvents();
                    if (i > 100 && !EnqueueOneStatisticOneTeamOneTimeFrame_Started) break;
                    i++;
                    //Thread.Sleep(100);
                    //Trace.TraceInformation("!EnqueueOneStatisticOneTeamOneTimeFrame_Finished ... retry in 1 sec");
                }

                ComputationException = null;
                excStr = string.Empty;
            }
            catch (Exception exc)
            {
                ComputationException = exc;
                excStr = string.Format("{0} {1}\r\n{2}", exc, exc.Message, exc.StackTrace.ToString());
                Trace.TraceError(excStr);
            }
            finally
            {
                queue.StatisticManagerQueueUpdated -= queueUpdated;
                queue.PropertyChanged -= queuePropUpdate;
            }
            Assert.IsNull(ComputationException, excStr);
            Assert.IsTrue(EnqueueOneStatisticOneTeamOneTimeFrame_Started, "Queue has not started");
            Assert.IsFalse(queue.IsCalculating, "Queue is still calculating");
            Assert.IsTrue(EnqueueOneStatisticOneTeamOneTimeFrame_Finished, "Queue has not finished");

        }

        void Queue_StatisticManagerQueueUpdated(object sender, StatisticManagerQueueUpdatedEventArgs e, int totalStatCount, ref int lastDifferenceFromTotal)
        {
            Trace.TraceInformation("Thread {3}, Queue update: WS={0}, FS={1}, Calculating={2}", e.WaitingStatsCount, e.FinishedStatsCount, e.IsCalculating, Thread.CurrentThread.Name);
            //totalStatCount = e.WaitingStatsCount + e.FinishedStatsCount;
            var diff = totalStatCount - (e.WaitingStatsCount + e.FinishedStatsCount);
            Assert.IsTrue(diff <= lastDifferenceFromTotal, "allowedDiffFromTotal>lastDifferenceFromTotal - Test if in each update the difference between total count and actual count is becoming lower or remains the same failed.");
            Assert.IsTrue(diff >= 0, "Total tf count = {0}, WS={1}, FS={2}, allowedDiffFromTotal={3}, lastDifferenceFromTotal={4}", totalStatCount, e.WaitingStatsCount, e.FinishedStatsCount, diff, lastDifferenceFromTotal);
        }

        void Queue_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e, ref bool Started, ref bool Finished)
        {
            Trace.TraceInformation("IStatisticManagerQueue value {0} changed.", e.PropertyName);
            if (e.PropertyName == "IsCalculating")
            {
                if (((IStatisticManagerQueue)sender).IsCalculating)
                {
                    Started = true;
                }
                else
                {
                    Finished = true;
                }
            }
        }


        //private bool EnqueueAllWIStatisticAllTeamsAllTimeFrames_Finished;
        //private bool EnqueueAllWIStatisticAllTeamsAllTimeFrames_Started;
        [TestMethod]
        public void EnqueueAllWIStatisticOneTeamOneTimeFrame()
        {
            InstantiateTestBootStrapper();
            var EnqueueAllWIStatisticOneTeamOneTimeFrame_Finished = false;
            var EnqueueAllWIStatisticOneTeamOneTimeFrame_Started = false;
            var sm = IPowersourceExt.StatisticManager;
            var WIstats = sm.AvailableStatistics.Values.Where(a => a is UCL.Powersource.Statistics.WIStateStatisticsBase);
            var totalCnt = WIstats.Count();
            var queue = sm.StatisticManagerQueue;
            int allowedDiffFromTotal = totalCnt;
            var queueUpdated = new EventHandler<StatisticManagerQueueUpdatedEventArgs>((sender, e) => Queue_StatisticManagerQueueUpdated(sender, e, totalCnt, ref allowedDiffFromTotal));
            var queuePropUpdate = new PropertyChangedEventHandler((sender, e) => Queue_PropertyChanged(sender, e, ref EnqueueAllWIStatisticOneTeamOneTimeFrame_Started, ref EnqueueAllWIStatisticOneTeamOneTimeFrame_Finished));
            queue.StatisticManagerQueueUpdated += queueUpdated;
            queue.PropertyChanged += queuePropUpdate;
            string excStr;
            Exception ComputationException;
            try
            {
                var team = MainVM.CurrentTfsTeamProjectCollectionConfiguration.First();
                var tf = MainVM.CurrentTfsTeamProjectCollectionConfiguration.ProjectCollectionTimeFrames.First();
                foreach (var stat in WIstats)
                {
                    queue.EnqueueStatisticRecalculationAsync(stat, team, tf, true);
                }
                int i = 0;
                Trace.TraceInformation("Entering waiting loop");
                while (!EnqueueAllWIStatisticOneTeamOneTimeFrame_Finished)
                {

                    //Trace.TraceInformation("!EnqueueOneStatisticOneTeamOneTimeFrame_Finished ... retry in 1 sec");
                    //Thread.Sleep(1000);
                    DispatcherUtil.DoEvents();
                    if (i > 100 && !EnqueueAllWIStatisticOneTeamOneTimeFrame_Started) break;
                    i++;
                }
                ComputationException = null;
                excStr = string.Empty;
            }
            catch (Exception exc)
            {
                ComputationException = exc;
                excStr = string.Format("{0} {1}\r\n{2}", exc, exc.Message, exc.StackTrace.ToString());
                Trace.TraceError(excStr);
            }
            finally
            {
                queue.StatisticManagerQueueUpdated -= queueUpdated;
                queue.PropertyChanged -= queuePropUpdate;
            }
            Assert.IsNull(ComputationException, excStr);
            Assert.IsFalse(queue.IsCalculating, "Queue is still calculating");
            Assert.IsTrue(EnqueueAllWIStatisticOneTeamOneTimeFrame_Started, "Queue has not started");
            Assert.IsTrue(EnqueueAllWIStatisticOneTeamOneTimeFrame_Finished, "Queue has not finished");

        }


        [TestMethod]
        public void EnqueueAllWIStatisticAllTeamsAllTimeFramesWithoutBuild()
        {
            InstantiateTestBootStrapper();
            var EnqueueAllWIStatisticAllTeamsAllTimeFrames_Finished = false;
            var EnqueueAllWIStatisticAllTeamsAllTimeFrames_Started = false;
            var sm = IPowersourceExt.StatisticManager;
            var teams = MainVM.CurrentTfsTeamProjectCollectionConfiguration;
            var timeframes = MainVM.CurrentTfsTeamProjectCollectionConfiguration.ProjectCollectionTimeFrames;
            var WIstats = sm.AvailableStatistics.Values.Where(a => !a.RequiresBuild);
            var totalCnt = WIstats.Count() * teams.Count() * timeframes.Count();
            var queue = sm.StatisticManagerQueue;
            int allowedDiffFromTotal = totalCnt;
            var queueUpdated = new EventHandler<StatisticManagerQueueUpdatedEventArgs>((sender, e) => Queue_StatisticManagerQueueUpdated(sender, e, totalCnt, ref allowedDiffFromTotal));
            var queuePropUpdate = new PropertyChangedEventHandler((sender, e) => Queue_PropertyChanged(sender, e, ref EnqueueAllWIStatisticAllTeamsAllTimeFrames_Started, ref EnqueueAllWIStatisticAllTeamsAllTimeFrames_Finished));
            queue.StatisticManagerQueueUpdated += queueUpdated;
            queue.PropertyChanged += queuePropUpdate;
            try
            {
                foreach (var team in teams)
                {
                    foreach (var tf in timeframes)
                    {

                        foreach (var stat in WIstats)
                        {
                            queue.EnqueueStatisticRecalculationAsync(stat, team, tf, true);
                        }
                    }
                }
                int i = 0;
                Trace.TraceInformation("Entering waiting loop");
                while (!EnqueueAllWIStatisticAllTeamsAllTimeFrames_Finished)
                {

                    //Trace.TraceInformation("!EnqueueOneStatisticOneTeamOneTimeFrame_Finished ... retry in 1 sec");
                    //Thread.Sleep(1000);
                    DispatcherUtil.DoEvents();
                    if (i > 100 && !EnqueueAllWIStatisticAllTeamsAllTimeFrames_Started) break;
                    i++;
                }
                Assert.IsFalse(queue.IsCalculating, "Queue is still calculating");
                Assert.IsTrue(EnqueueAllWIStatisticAllTeamsAllTimeFrames_Started, "Queue has not started");
                Assert.IsTrue(EnqueueAllWIStatisticAllTeamsAllTimeFrames_Finished, "Queue has not finished");
            }
            catch (Exception exc)
            {
                var excStr = string.Format("{0} {1}\r\n{2}", exc, exc.Message, exc.StackTrace.ToString());
                Trace.TraceError(excStr);
                Assert.Fail(excStr);
            }
            finally
            {
                queue.StatisticManagerQueueUpdated -= queueUpdated;
                queue.PropertyChanged -= queuePropUpdate;
            }


        }

        [TestMethod]
        public void EnqueueOneStatisticWithBuildTestTeam1Release1()
        {
            InstantiateTestBootStrapper();
            //MainVM.ConnectToTFS("http://81.2.210.131:8080/tfs/FabrikamFiberCollection/");
            var EnqueueOneStatisticWithBuildTeamOneTimeFrame_Finished = false;
            var EnqueueOneStatisticWithBuildTeamOneTimeFrame_Started = false;
            var sm = IPowersourceExt.StatisticManager;
            var queue = sm.StatisticManagerQueue;
            var totalCnt = 1;
            int allowedDiffFromTotal = totalCnt;
            var queueUpdated = new EventHandler<StatisticManagerQueueUpdatedEventArgs>((sender, e) => Queue_StatisticManagerQueueUpdated(sender, e, totalCnt, ref allowedDiffFromTotal));
            var queuePropUpdate = new PropertyChangedEventHandler((sender, e) => Queue_PropertyChanged(sender, e, ref EnqueueOneStatisticWithBuildTeamOneTimeFrame_Started, ref EnqueueOneStatisticWithBuildTeamOneTimeFrame_Finished));
            queue.StatisticManagerQueueUpdated += queueUpdated;
            queue.PropertyChanged += queuePropUpdate;
            string excStr;
            Exception ComputationException;
            IStatisticManagerQueueItem statisticRecalculationItem = null;
            try
            {
                var stat = sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.CodeIndex.RFCStatisticMaximum));
                var team = MainVM.CurrentTfsTeamProjectCollectionConfiguration.First();
                var tf = MainVM.CurrentTfsTeamProjectCollectionConfiguration.ProjectCollectionTimeFrames.First();
                team.SolutionFilePath = "FabrikamFiber.CallCenter/FabrikamFiber.CallCenter.sln";
                statisticRecalculationItem = queue.EnqueueStatisticRecalculationAsync(stat, team, tf, true);
                int i = 0;
                Trace.TraceInformation("Entering waiting loop");
                while (!EnqueueOneStatisticWithBuildTeamOneTimeFrame_Finished)
                {

                    DispatcherUtil.DoEvents();
                    if (i > 100 && !EnqueueOneStatisticWithBuildTeamOneTimeFrame_Started) break;
                    i++;
                    //Thread.Sleep(100);
                    //Trace.TraceInformation("!EnqueueOneStatisticOneTeamOneTimeFrame_Finished ... retry in 1 sec");
                }

                ComputationException = null;
                excStr = string.Empty;
            }
            catch (Exception exc)
            {
                ComputationException = exc;
                excStr = string.Format("{0} {1}\r\n{2}", exc, exc.Message, exc.StackTrace.ToString());
                Trace.TraceError(excStr);
            }
            finally
            {
                queue.StatisticManagerQueueUpdated -= queueUpdated;
                queue.PropertyChanged -= queuePropUpdate;
            }
            Trace.WriteLine("{0}", statisticRecalculationItem.ToString());
            Assert.IsNotNull(statisticRecalculationItem, "statisticRecalculationItem==null");
            Assert.IsTrue(statisticRecalculationItem.Status == QueuedItemStatus.Finished);
            Assert.IsTrue(statisticRecalculationItem.RemoteBuilderQueueItem.Status == QueuedItemStatus.Finished);
            Assert.IsTrue(
                statisticRecalculationItem.RemoteBuilderQueueItem.BuildDetail.Status == Microsoft.TeamFoundation.Build.Client.BuildStatus.Succeeded
                ||
                statisticRecalculationItem.RemoteBuilderQueueItem.BuildDetail.Status == Microsoft.TeamFoundation.Build.Client.BuildStatus.PartiallySucceeded,
                "Compilation failed!"
                );
            // statisticRecalculationItem.ComputationException
            Assert.IsNull(ComputationException, excStr);
            Assert.IsTrue(EnqueueOneStatisticWithBuildTeamOneTimeFrame_Started, "Queue has not started");
            Assert.IsFalse(queue.IsCalculating, "Queue is still calculating");
            Assert.IsTrue(EnqueueOneStatisticWithBuildTeamOneTimeFrame_Finished, "Queue has not finished");

        }

        [TestMethod]
        public void EnqueueOneStatisticWithBuildTestCollection()
        {
            InstantiateTestBootStrapper();   
            //LogManager.DefaultInstance.AddLog(new FileLog(VerbosityLevels.Debug, string.Format("D:\\temp\\LOGS\\Powersource-{0:yyyyMMdd}.log",DateTime.Now)));
            
            //MainVM.ConnectToTFS("http://81.2.210.131:8080/tfs/FabrikamFiberCollection/");
            var EnqueueOneStatisticWithBuildTestCollection_Finished = false;
            var EnqueueOneStatisticWithBuildTestCollection_Started = false;
            var sm = IPowersourceExt.StatisticManager;
            var queue = sm.StatisticManagerQueue;
            var teams = MainVM.CurrentTfsTeamProjectCollectionConfiguration;
            var timeframes = MainVM.CurrentTfsTeamProjectCollectionConfiguration.ProjectCollectionTimeFrames;
            List<IStatistic> stats = new List<IStatistic>();
            stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.NumberOfClassesStats)));
            stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.NumberOfMethodsStats)));
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.CodeIndex.RFCStatisticMinimum)));
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.CodeIndex.RFCStatisticAverage)));
            teams.CodeIndexDBServer = "(localdb)\\v11.0";
            var totalCnt = teams.Count()*timeframes.Count()*stats.Count();
            int allowedDiffFromTotal = totalCnt;
            var team1 = teams.First(a => a.UniqueName == "TestProjectTeam1");
            var team2 = teams.First(a => a.UniqueName == "TestProjectTeam2");
            team2.SolutionFilePath = "TestMvcApplication/TestMvcApplication.sln";
            var team3 = teams.First(a => a.UniqueName == "TestProjectTeam3");
            team3.SolutionFilePath = "TestWpfApplication/TestWpfApplication.sln";
            var team4 = teams.First(a => a.UniqueName == "TestProjectTeam4");
            team4.SolutionFilePath = "AnotherWpfApplication/AnotherWpfApplication.sln";
            var team5 = teams.First(a => a.UniqueName == "TestProjectTeam5");
            
            team1.IsChosen = true;
            team2.IsChosen = true;
            team3.IsChosen = true;
            team4.IsChosen = true;
            team5.IsChosen = true;

            Assert.IsTrue(teams.All(a => a.IsValidForStatistic));


            string excStr;
            Exception ComputationException;
            IStatisticManagerQueueItem statisticRecalculationItem = null;
            try
            {
                
                var queueUpdated = new EventHandler<StatisticManagerQueueUpdatedEventArgs>((sender, e) => Queue_StatisticManagerQueueUpdated(sender, e, totalCnt, ref allowedDiffFromTotal));
                var queuePropUpdate = new PropertyChangedEventHandler((sender, e) => Queue_PropertyChanged(sender, e, ref EnqueueOneStatisticWithBuildTestCollection_Started, ref EnqueueOneStatisticWithBuildTestCollection_Finished));
                //team.SolutionFilePath = "FabrikamFiber.CallCenter/FabrikamFiber.CallCenter.sln";
                foreach (var team in teams)
                {
                    foreach (var tf in timeframes)
                    {
                        foreach (var stat in stats)
                        {

                            try
                            {

                                EnqueueOneStatisticWithBuildTestCollection_Started = false;
                                EnqueueOneStatisticWithBuildTestCollection_Finished = false;

                                queue.StatisticManagerQueueUpdated += queueUpdated;
                                queue.PropertyChanged += queuePropUpdate;
                                statisticRecalculationItem = queue.EnqueueStatisticRecalculationAsync(stat, team, tf, true);
                                int i = 0;
                                Trace.TraceInformation("CALCULATION STARTED: {0} - Count of statres: {1}", statisticRecalculationItem.ToString(), statisticRecalculationItem.Statistic.Results.Count());
                                while (!EnqueueOneStatisticWithBuildTestCollection_Finished)
                                {

                                    DispatcherUtil.DoEvents();
                                    if (i > 100 && !EnqueueOneStatisticWithBuildTestCollection_Started) break;
                                    i++;
                                    //Thread.Sleep(100);
                                    //Trace.TraceInformation("!EnqueueOneStatisticOneTeamOneTimeFrame_Finished ... retry in 1 sec");
                                }

                                Trace.TraceInformation("CALCULATION FINISHED: {0} - Count of statres: {1}", statisticRecalculationItem.ToString(), statisticRecalculationItem.Statistic.Results.Count());
                                //team.ProjectAnalysisBridge.Pop(statisticRecalculationItem.RemoteBuilderQueueItem.BuildDetail);
                            }
                            finally
                            {
                                queue.StatisticManagerQueueUpdated -= queueUpdated;
                                queue.PropertyChanged -= queuePropUpdate;

                            }
                            ComputationException = null;
                            excStr = string.Empty;
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                ComputationException = exc;
                excStr = string.Format("{0} {1}\r\n{2}", exc, exc.Message, exc.StackTrace.ToString());
                Trace.TraceError(excStr);
                Assert.Fail(excStr);
            }
            
            Trace.WriteLine("{0}", statisticRecalculationItem.ToString());
            Assert.IsNotNull(statisticRecalculationItem, "statisticRecalculationItem==null");
            Assert.IsTrue(statisticRecalculationItem.Status == QueuedItemStatus.Finished);
            Assert.IsTrue(EnqueueOneStatisticWithBuildTestCollection_Started, "Queue has not started");
            Assert.IsFalse(queue.IsCalculating, "Queue is still calculating");
            Assert.IsTrue(EnqueueOneStatisticWithBuildTestCollection_Finished, "Queue has not finished");

        }

        [TestMethod]
        public void EnqueueRFCStatisticWithBuildTestCollection()
        {
            InstantiateTestBootStrapper();
            //LogManager.DefaultInstance.AddLog(new FileLog(VerbosityLevels.Debug, string.Format("D:\\temp\\LOGS\\Powersource-{0:yyyyMMdd}.log",DateTime.Now)));

            //MainVM.ConnectToTFS("http://81.2.210.131:8080/tfs/FabrikamFiberCollection/");
            var sm = IPowersourceExt.StatisticManager;
            var queue = sm.StatisticManagerQueue;
            var teams = MainVM.CurrentTfsTeamProjectCollectionConfiguration;
            var timeframes = MainVM.CurrentTfsTeamProjectCollectionConfiguration.ProjectCollectionTimeFrames;
            List<IStatistic> stats = new List<IStatistic>();
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.NumberOfClassesStats)));
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.NumberOfMethodsStats)));
            stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.CodeIndex.RFCStatisticMinimum)));
            stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.CodeIndex.RFCStatisticAverage)));
            teams.CodeIndexDBServer = "(localdb)\\v11.0";
            var totalCnt = teams.Count() * timeframes.Count() * stats.Count();
            int allowedDiffFromTotal = totalCnt;
            var team1 = teams.First(a => a.UniqueName == "TestProjectTeam1");
            var team2 = teams.First(a => a.UniqueName == "TestProjectTeam2");
            team2.SolutionFilePath = "TestMvcApplication/TestMvcApplication.sln";
            var team3 = teams.First(a => a.UniqueName == "TestProjectTeam3");
            team3.SolutionFilePath = "TestWpfApplication/TestWpfApplication.sln";
            var team4 = teams.First(a => a.UniqueName == "TestProjectTeam4");
            team4.SolutionFilePath = "AnotherWpfApplication/AnotherWpfApplication.sln";
            var team5 = teams.First(a => a.UniqueName == "TestProjectTeam5");

            team1.IsChosen = true;
            team2.IsChosen = true;
            team3.IsChosen = true;
            team4.IsChosen = true;
            team5.IsChosen = true;

            Assert.IsTrue(teams.All(a => a.IsValidForStatistic));

            foreach (var stat in stats)
            {
          
                foreach (var team in teams)
                {
                    foreach (var tf in timeframes)
                    {
                        sm.ResolveStatistic(stat.GetType(), team, tf, true);
                    }
                }
                Assert.AreEqual(stat.TeamResults.Count(), teams.Count() * timeframes.Count());

            }

        }

        [TestMethod]
        public void EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames()
        {
            InstantiateTestBootStrapper();
            //LogManager.DefaultInstance.AddLog(new FileLog(VerbosityLevels.Debug, string.Format("D:\\temp\\LOGS\\Powersource-{0:yyyyMMdd}.log",DateTime.Now)));

            //MainVM.ConnectToTFS("http://81.2.210.131:8080/tfs/FabrikamFiberCollection/");
            var EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Finished = false;
            var EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Started = false;
            var sm = IPowersourceExt.StatisticManager;
            var queue = sm.StatisticManagerQueue;
            var teams = MainVM.CurrentTfsTeamProjectCollectionConfiguration;
            var timeframes = MainVM.CurrentTfsTeamProjectCollectionConfiguration.ProjectCollectionTimeFrames;
            List<IStatistic> stats = new List<IStatistic>();
            //stats.Add(sm.GetStatisticOrDefault(NobukoAnalyzer.NobukoStatistic.NobukoStat_Statistic_Guid));
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.NumberOfClassesStats)));
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.NumberOfMethodsStats)));
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.CodeIndex.RFCStatisticMinimum)));
            //stats.Add(sm.GetStatisticOrDefault(typeof(UCL.Powersource.Statistics.CodeIndex.RFCStatisticAverage)));
            teams.CodeIndexDBServer = "(localdb)\\v11.0";
            var totalCnt = teams.Count() * timeframes.Count() * stats.Count();
            int allowedDiffFromTotal = totalCnt;
            var team1 = teams.First(a => a.UniqueName == "TestProjectTeam1");
            var team2 = teams.First(a => a.UniqueName == "TestProjectTeam2");
            team2.SolutionFilePath = "TestMvcApplication/TestMvcApplication.sln";
            var team3 = teams.First(a => a.UniqueName == "TestProjectTeam3");
            team3.SolutionFilePath = "TestWpfApplication/TestWpfApplication.sln";
            var team4 = teams.First(a => a.UniqueName == "TestProjectTeam4");
            team4.SolutionFilePath = "AnotherWpfApplication/AnotherWpfApplication.sln";
            var team5 = teams.First(a => a.UniqueName == "TestProjectTeam5");



            team1.IsChosen = true;
            team2.IsChosen = true;
            team3.IsChosen = true;
            team4.IsChosen = true;
            team5.IsChosen = true;

            Assert.IsTrue(teams.Count(a => a.IsValidForStatistic) == 5);
            var teamsToGoOver = teams.Where(a => a.IsValidForStatistic);

            string excStr;
            Exception ComputationException;
            IStatisticManagerQueueItem statisticRecalculationItem = null;
            try
            {

                var queueUpdated = new EventHandler<StatisticManagerQueueUpdatedEventArgs>((sender, e) => Queue_StatisticManagerQueueUpdated(sender, e, totalCnt, ref allowedDiffFromTotal));
                var queuePropUpdate = new PropertyChangedEventHandler((sender, e) => Queue_PropertyChanged(sender, e, ref EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Started, ref EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Finished));
                //team.SolutionFilePath = "FabrikamFiber.CallCenter/FabrikamFiber.CallCenter.sln";
                foreach (var team in teamsToGoOver)
                {
                    foreach (var tf in timeframes)
                    {
                        foreach (var stat in stats)
                        {

                            try
                            {

                                EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Started = false;
                                EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Finished = false;

                                queue.StatisticManagerQueueUpdated += queueUpdated;
                                queue.PropertyChanged += queuePropUpdate;
                                statisticRecalculationItem = queue.EnqueueStatisticRecalculationAsync(stat, team, tf, false);
                                int i = 0;
                                Log.Trace("CALCULATION STARTED: {0} {1}- Count of statres: {2}", DateTime.Now, statisticRecalculationItem.ToString(), statisticRecalculationItem.Statistic.Results.Count());
                                while (!EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Finished)
                                {

                                    DispatcherUtil.DoEvents();
                                    if (i > 100 && !EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Started) break;
                                    i++;
                                    //Thread.Sleep(100);
                                    //Trace.TraceInformation("!EnqueueOneStatisticOneTeamOneTimeFrame_Finished ... retry in 1 sec");
                                }

                                Log.Trace("CALCULATION FINISHED: {0} {1}- Count of statres: {2}", DateTime.Now, statisticRecalculationItem.ToString(), statisticRecalculationItem.Statistic.Results.Count());
                                //team.ProjectAnalysisBridge.Pop(statisticRecalculationItem.RemoteBuilderQueueItem.BuildDetail);
                            }
                            finally
                            {
                                queue.StatisticManagerQueueUpdated -= queueUpdated;
                                queue.PropertyChanged -= queuePropUpdate;

                            }
                            ComputationException = null;
                            excStr = string.Empty;
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                ComputationException = exc;
                excStr = string.Format("{0} {1}\r\n{2}", exc, exc.Message, exc.StackTrace.ToString());
                Trace.TraceError(excStr);
                Assert.Fail(excStr);
            }

            Trace.WriteLine("{0}", statisticRecalculationItem.ToString());
            Assert.IsNotNull(statisticRecalculationItem, "statisticRecalculationItem==null");
            Assert.IsTrue(statisticRecalculationItem.Status == QueuedItemStatus.Finished);
            Assert.IsTrue(EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Started, "Queue has not started");
            Assert.IsFalse(queue.IsCalculating, "Queue is still calculating");
            Assert.IsTrue(EnqueueNobukoStatisticWith2TeamsAnd2TimeFrames_Finished, "Queue has not finished");

        }

    }
}
